using Engine;
using SharpDX;
using System.Collections.Generic;

namespace street
{
    internal class Meshes
    {
        #region Public Methods

        public static void CreateRoadside(ref Vector3[] middle, ref List<Vector3> vertices, ref List<Vector2> uvCoordinates, ref List<short> indices, ref List<int> polyTextures, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, float textureUcoordinates)
        {
            short OffsetIndices = (short)(vertices.Count);

            polyTextures.Add((middle.Length - 1) * 2);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((short)(point + OffsetIndices));
                indices.Add((short)(point + 1 + OffsetIndices));
                indices.Add((short)(point + 2 + OffsetIndices));

                indices.Add((short)(point + 1 + OffsetIndices));
                indices.Add((short)(point + 3 + OffsetIndices));
                indices.Add((short)(point + 2 + OffsetIndices));
                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            vertices.Add(middle[0] - rightPoint);
            uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));
            vertices.Add(middle[0] + rightPoint);
            uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));

            textureUcoordinates += middleLineDistances[0] / 10; //DistanceBtw2Points(middle[0], middle[0 + 1]) / 10.0f;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));
                if (i < (middle.Length - 1))
                    rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);
                else
                    rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);
                vertices.Add(middle[i] - rightPoint);
                uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));
                vertices.Add(middle[i] + rightPoint);
                uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));
                textureUcoordinates += middleLineDistances[i] / 10;
            }

            //rightPoint = makePointFromAngel(middle[0], anglePointTwo - 180, widthPointTwo, inclinationPointTwo);
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);
            vertices.Add(middle[middle.Length - 1] - rightPoint);
            uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));
            vertices.Add(middle[middle.Length - 1] + rightPoint);
            uvCoordinates.Add(new Vector2(-vertices[vertices.Count - 1].X / 10, vertices[vertices.Count - 1].Z / 10));

            textureUcoordinates = 0;
        }

        /// <summary>
        /// This creates a new Middle Line. The middleline has a minimum segment length
        /// </summary>
        /// <param name="middle"></param>
        /// <param name="segmentLength">every segment will have at least this length. Or a bit longer</param>
        /// <returns></returns>
        public static void CreateWall(ref Vector3[] middle, ref List<Vector3> vertices, ref List<Vector2> uvCoordinates, ref List<short> indices, ref List<int> polyTextures, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, float textureUcoordinates)
        {
            short OffsetIndices = (short)(vertices.Count);

            polyTextures.Add((middle.Length - 1) * 2);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((short)(point + OffsetIndices));
                indices.Add((short)(point + 1 + OffsetIndices));
                indices.Add((short)(point + 2 + OffsetIndices));

                //indices.Add((short)(point + OffsetIndices));
                //indices.Add((short)(point + 2 + OffsetIndices));
                //indices.Add((short)(point + 1 + OffsetIndices));

                indices.Add((short)(point + 1 + OffsetIndices));
                indices.Add((short)(point + 3 + OffsetIndices));
                indices.Add((short)(point + 2 + OffsetIndices));

                //indices.Add((short)(point + 1 + OffsetIndices));
                //indices.Add((short)(point + 2 + OffsetIndices));
                //indices.Add((short)(point + 3 + OffsetIndices));

                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);
            vertices.Add(middle[0]);
            vertices.Add(middle[0] + rightPoint);
            uvCoordinates.Add(new Vector2(0.0f, textureUcoordinates));
            uvCoordinates.Add(new Vector2(textureUcoordinates, -1.0f));

            textureUcoordinates += middleLineDistances[0] / 10; //DistanceBtw2Points(middle[0], middle[0 + 1]) / 10.0f;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));
                //if (i < (middle.Length - 1))
                //    rightPoint = makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);
                //else
                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);
                vertices.Add(middle[i]);
                vertices.Add(middle[i] + rightPoint);
                uvCoordinates.Add(new Vector2(textureUcoordinates, 0.0f));
                uvCoordinates.Add(new Vector2(textureUcoordinates, -1.0f));
                if (i < middle.Length - 1)
                    //textureUcoordinates += middleLineDistances[i] / 10;
                    textureUcoordinates += middleLineDistances[i] / 10.0f;
            }

            //rightPoint = makePointFromAngel(middle[0], anglePointTwo - 180, widthPointTwo, inclinationPointTwo);
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);
            vertices.Add(middle[middle.Length - 1]);
            vertices.Add(middle[middle.Length - 1] + rightPoint);
            uvCoordinates.Add(new Vector2(textureUcoordinates, 0.0f));
            uvCoordinates.Add(new Vector2(textureUcoordinates, -1.0f));

            textureUcoordinates = 0;
        }

        #endregion Public Methods
    }
}